import datetime
import json

from django.core.paginator import Paginator
from django.db.models import Q
from django.http import HttpResponse
from django.shortcuts import render
from django.views.decorators.http import require_POST, require_GET
from jwt.exceptions import InvalidSignatureError, ExpiredSignatureError

from utils.customer_util import CustomerUtil
from utils.response_code import ResponseCode
from .models import User

from django_vue_back_2512 import settings
from django.db import connection

# Create your views here.
"""
  认证流程分析:
  1.  /users/login   post  username password   json格式
  2.  接收json格式参数   request.body   -> dict
  3.  username password   查询数据库  mysql 
  4.  判定用户是否存在  
     4.1  存在    is_active     0  禁用  失败   1  成功
     4.2  不存在    直接返回数据  认证失败  
  5. 用户认证通过  
         create token    jwt  json web token 
         token的数据格式
             xxxx.yyyy.zzzz
             xxxx: 表示token的头部信息   
                { "alg": "HS256","typ": "JWT"}   
                this JSON is Base64Url encoded to form the first part of the JWT
             yyyy: 载荷  用户信息  username  id  roles   不要存储敏感信息   token 保存在客户端  安全问题
                { "sub": "1234567890", "name": "John Doe","admin": true} 
                Base64Url encoded to form the second part of the JSON Web Token
             zzz： 签名   鉴定token的真伪    secret  秘钥  
             HMACSHA256( base64UrlEncode(header) + "." + base64UrlEncode(payload),secret)
             
             返回标准格式的数据   json
            {
                'code': 20000,
                'message':'添加成功',
                 total:1000,
                 table_data:[{},{},....]
            }
            
Access to XMLHttpRequest at 'http://localhost:8000/users/login' 
from origin 'http://localhost:9528' has been blocked by CORS policy
 请求违背了浏览器的同源策略 
 to: http://localhost:8000       from :http://localhost:9528
 请求协议  http
 域名:  IP localhost
 端口:  port 8000
 
 如何解决跨域问题 
   1. 前端 配置代理服务器
   2. 后端 所有接口允许跨域请求   Django
"""


def login_view(request):
    if request.method == "POST":
        # 接收数据
        params_dict = CustomerUtil.get_request_params(request)
        # 加密
        params_dict['password'] = CustomerUtil.md5(params_dict['password'])
        # 查询数据库  {username:'admin','password':'adsdfgh'}
        db_user = User.objects.filter(**params_dict).first()
        if not db_user:
            # 用户名或密码错误
            return CustomerUtil.response_json({
                'code': ResponseCode.BUSINESS_ERROR,
                'message': '用户名或密码错误'
            })

        # 判定用户状态  is_active
        if db_user.is_active == 0:
            return CustomerUtil.response_json({
                'code': ResponseCode.BUSINESS_ERROR,
                'message': '账户被禁用,请联系管理员'
            })

        # 用户认证通过   create token
        payload = {
            'username': db_user.username,
            'uid': db_user.id,
            'exp': datetime.datetime.utcnow() + datetime.timedelta(days=1),
        }
        token = CustomerUtil.create_token(payload)
        # 响应成功的数据
        return CustomerUtil.response_json({
            'code': ResponseCode.BUSINESS_SUCCESS,
            'message': '认证通过',
            'data': {
                'token': token,
            }
        })
    else:
        return CustomerUtil.response_json({
            'code': ResponseCode.BUSINESS_ERROR,
            'message': '请求方式异常',
        })


#  /users/info?token=aaaaa
def user_info(request):
    if request.method == "GET":
        token = request.GET.get('token')
        #   解析token
        try:
            params_dict = CustomerUtil.decode_token(token)
            # 载荷  username  uid
            user = User.objects.filter(id=params_dict['uid']).first()
            response = {
                "code": ResponseCode.BUSINESS_SUCCESS,
                "message": "用户详细信息获取成功",
                "data": {
                    'name': user.nick_name,
                    'roles': [user.role.role_en],
                    'avatar': user.avatar
                }
            }
        except InvalidSignatureError as e:
            response = {
                "code": ResponseCode.ILLEGAL_TOKEN,
                "message": "token异常,请重新认证"
            }
        except ExpiredSignatureError as e:
            response = {
                "code": ResponseCode.TOKEN_EXPIRED,
                "message": "token过期,请重新认证"
            }

        return CustomerUtil.response_json(response)

    else:
        return CustomerUtil.response_json({
            'code': ResponseCode.BUSINESS_ERROR,
            'message': '请发送正确请求'
        })


@require_POST
def user_page(request):
    """用户信息分页"""
    params = CustomerUtil.get_request_params(request)
    page = params.get('page', 1)
    size = params.get('size', 5)
    # 搜索关键词  username  email  state
    username = params.get('username')
    email = params.get('email')
    is_active = params.get('is_active')

    print(username, email, is_active)

    #  构建空条件
    q = Q()
    # 构建动态sql  where  username = ?  and  email = ? and  is_active = ?
    if username.strip():
        q &= Q(username__contains=username)
    if email.strip():
        q &= Q(email__contains=email)
    if is_active.strip():
        q &= Q(is_active=is_active)

    users = User.objects.filter(q).order_by('-id')
    paginator = Paginator(users, size)
    total = paginator.count
    current_page = paginator.page(page)
    current_page_data = current_page.object_list
    table_data = []
    for user in current_page_data:
        item = {}
        item['id'] = user.id
        item['username'] = user.username
        item['nick_name'] = user.nick_name
        item['email'] = user.email
        item['age'] = user.age
        item['dept'] = user.dept.name
        item['role'] = user.role.role_zh
        item['is_active'] = user.is_active
        table_data.append(item)

    return CustomerUtil.response_json({
        'code': ResponseCode.BUSINESS_SUCCESS,
        'table_data': table_data,
        'total': total
    })


@require_POST
def user_state(request):
    params = CustomerUtil.get_request_params(request)
    active = params.get('active')
    id = params.get('id')
    User.objects.filter(id=id).update(is_active=active)
    return CustomerUtil.response_json({
        'code': ResponseCode.BUSINESS_SUCCESS,
        'message': '状态修改成功'
    })


@require_POST
def user_insert_edit(request):
    """新增和编辑用户信息"""
    params = CustomerUtil.get_request_params(request)
    try:
        if params.get('id'):
            User.objects.filter(id=params.get('id')).update(**params)
        else:
            # 添加默认密码
            params['password'] = CustomerUtil.md5(settings.DEFAULT_PASSWORD)
            User(**params).save()
        response = {
            'code': ResponseCode.BUSINESS_SUCCESS,
            'message': "操作成功"
        }
    except Exception as e:
        response = {
            'code': ResponseCode.BUSINESS_ERROR,
            'message': str(e)
        }

    return CustomerUtil.response_json(response)


@require_GET
def user_one(request, id):
    user = User.objects.filter(id=id).values().first()
    return CustomerUtil.response_json({
        'code': ResponseCode.BUSINESS_SUCCESS,
        'user': user
    })


@require_POST
def user_remove(request):
    # {ids:[]}
    params = CustomerUtil.get_request_params(request)
    # 删除用户信息
    User.objects.filter(id__in=params['ids']).delete()

    return CustomerUtil.response_json({
        'code': ResponseCode.BUSINESS_SUCCESS,
        'message': "删除成功"
    })


@require_GET
def user_bar_charts(request):
    """部门人数可视化
      [{},{}]
    """
    cursor = connection.cursor()
    # 游标对象
    str_sql = """  SELECT dept.`name`  as  `name` ,  count(user.id) AS `value`   
        FROM  `user`  LEFT JOIN dept
        ON  user.dept_id  = dept.id
        GROUP BY  user.dept_id
    """
    cursor.execute(str_sql)
    # 获取结果集
    data = list(cursor.fetchall())
    bar_data = []
    for dept in data:
        item = {}
        item['name'] = dept[0]
        item['value'] = dept[1]
        bar_data.append(item)
    return CustomerUtil.response_json({
        'code': ResponseCode.BUSINESS_SUCCESS,
        'bar_data': bar_data
    })
